package com.tio.tiowebscoketdemo.handler;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.tio.tiowebscoketdemo.common.WsBusType;
import com.tio.tiowebscoketdemo.common.intf.AbsShowcaseBsHandler;
import com.tio.tiowebscoketdemo.config.CaseServerConfig;
import com.tio.tiowebscoketdemo.handler.bus.HeartbeatReqHandler;
import com.tio.tiowebscoketdemo.handler.bus.LoginReqHandler;
import com.tio.tiowebscoketdemo.handler.bus.P2PReqHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.tio.core.ChannelContext;
import org.tio.core.Tio;
import org.tio.core.TioConfig;
import org.tio.http.common.HttpRequest;
import org.tio.http.common.HttpResponse;
import org.tio.websocket.common.WsRequest;
import org.tio.websocket.common.WsResponse;
import org.tio.websocket.common.WsSessionContext;
import org.tio.websocket.server.handler.IWsMsgHandler;

import java.util.HashMap;
import java.util.Map;

/**
 * @Author 955
 * @Date 2023-07-31 18:26
 * @Description
 */
@Slf4j
@Component
public class WebSocketMessageHandler implements IWsMsgHandler {
    /**
     * TIO-WEBSOCKET 配置信息
     */
    public static TioConfig serverTioConfig;

    private static Map<String, AbsShowcaseBsHandler<?>> handlerMap = new HashMap<>();
    static {
        handlerMap.put(WsBusType.HEART_BEAT_REQ, new HeartbeatReqHandler());
        handlerMap.put(WsBusType.LOGIN_REQ, new LoginReqHandler());
        handlerMap.put(WsBusType.P2P_REQ, new P2PReqHandler());
    }

    @Override
    public HttpResponse handshake(HttpRequest httpRequest, HttpResponse httpResponse, ChannelContext channelContext) throws Exception {
        serverTioConfig = channelContext.tioConfig;
        return httpResponse;
    }

    @Override
    public void onAfterHandshaked(HttpRequest httpRequest, HttpResponse httpResponse, ChannelContext channelContext) throws Exception {
        // 拿到用户id
        String id = httpRequest.getParam("id");
        // 绑定用户
        Tio.bindUser(channelContext, id);

        // 绑定业务类型(根据业务类型判定处理相关业务)
        String bsId = httpRequest.getParam("bsId");
        if (StrUtil.isNotBlank(bsId)) {
            Tio.bindBsId(channelContext, bsId);
        }
        // 给用户发送消息
        WsResponse wsResponse = WsResponse.fromText("您已成功连接 WebSocket 服务器", "UTF-8");
        Tio.sendToUser(channelContext.tioConfig, id, wsResponse);
    }

    @Override
    public Object onBytes(WsRequest wsRequest, byte[] bytes, ChannelContext channelContext) throws Exception {
        return null;
    }

    @Override
    public Object onClose(WsRequest wsRequest, byte[] bytes, ChannelContext channelContext) throws Exception {
        // 关闭连接
        Tio.remove(channelContext, "WebSocket Close");
        return null;
    }

    @Override
    public Object onText(WsRequest wsRequest, String text, ChannelContext channelContext) throws Exception {
        WsSessionContext wsSessionContext = (WsSessionContext) channelContext.get();
        HttpRequest httpRequest = wsSessionContext.getHandshakeRequest();//获取websocket握手包
        if (log.isDebugEnabled()) {
            log.debug("握手包:{}", httpRequest);
        }

        log.debug("收到ws消息:{}", text);

        String type = null;
        try {
            type = (String) JSONUtil.parseObj(text).get("type");
        } catch (Exception e) {
           log.error("解析type异常");
        }
        AbsShowcaseBsHandler<?> showcaseBsHandler = handlerMap.get(type);

        if (showcaseBsHandler == null) {
            log.error("{}, 找不到处理类，type:{}", channelContext, type);
            String msg = "{'message:'【" + text + "】类型不正确" + "'}";
            //用tio-websocket，服务器发送到客户端的Packet都是WsResponse
            WsResponse wsResponse = WsResponse.fromText(msg, CaseServerConfig.CHARSET);
            Tio.send(channelContext, wsResponse);
            return null;
        }
        return showcaseBsHandler.handler(wsRequest, channelContext);
    }
}